package com.yanggu.common.sensitive;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import cn.hutool.v7.core.data.masking.MaskingUtil;
import cn.hutool.v7.core.text.CharSequenceUtil;
import cn.hutool.v7.core.text.StrUtil;

import java.io.IOException;
import java.util.Objects;

/**
 * 脱敏注解自定义序列化类
 */
@NoArgsConstructor
@AllArgsConstructor
public class DesensitizationSerialize extends JsonSerializer<String> implements ContextualSerializer {

    private DesensitizationTypeEnum type;

    private Integer startInclude;

    private Integer endExclude;

    @Override
    public void serialize(String str, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
        switch (type) {
            //自定义类型脱敏
            case MY_RULE:
                jsonGenerator.writeString(CharSequenceUtil.hide(str, startInclude, endExclude));
                break;
            //userId脱敏
            case USER_ID:
                jsonGenerator.writeString(String.valueOf(MaskingUtil.userId()));
                break;
            //中文姓名脱敏
            case CHINESE_NAME:
                jsonGenerator.writeString(MaskingUtil.chineseName(String.valueOf(str)));
                break;
            //身份证脱敏
            case ID_CARD:
                jsonGenerator.writeString(MaskingUtil.idCardNum(String.valueOf(str), 1, 2));
                break;
            //固定电话脱敏
            case FIXED_PHONE:
                jsonGenerator.writeString(MaskingUtil.fixedPhone(String.valueOf(str)));
                break;
            //手机号脱敏
            case MOBILE_PHONE:
                int length = str.length();
                if (length == 8) {
                    jsonGenerator.writeString(StrUtil.hide(str, 2, str.length() - 3));
                } else {
                    jsonGenerator.writeString(MaskingUtil.mobilePhone(str));
                }
                break;
            //地址脱敏
            case ADDRESS:
                jsonGenerator.writeString(MaskingUtil.address(String.valueOf(str), 8));
                break;
            //邮箱脱敏
            case EMAIL:
                jsonGenerator.writeString(MaskingUtil.email(String.valueOf(str)));
                break;
            //密码脱敏
            case PASSWORD:
                jsonGenerator.writeString(MaskingUtil.password(String.valueOf(str)));
                break;
            //中国车牌脱敏
            case CAR_LICENSE:
                jsonGenerator.writeString(MaskingUtil.carLicense(String.valueOf(str)));
                break;
            //银行卡脱敏
            case BANK_CARD:
                jsonGenerator.writeString(MaskingUtil.bankCard(String.valueOf(str)));
                break;
            default:
        }

    }

    @Override
    public JsonSerializer<?> createContextual(SerializerProvider serializerProvider, BeanProperty beanProperty) throws JsonMappingException {
        if (beanProperty != null) {
            //判断数据类型是否为String类型
            if (Objects.equals(beanProperty.getType().getRawClass(), String.class)) {
                //获取定义的注解
                Desensitization desensitization = beanProperty.getAnnotation(Desensitization.class);
                //为null
                if (desensitization == null) {
                    desensitization = beanProperty.getContextAnnotation(Desensitization.class);
                }
                //不为null
                if (desensitization != null) {
                    //创建定义的序列化类的实例并且返回，入参为注解定义的type,开始位置，结束位置。
                    return new DesensitizationSerialize(desensitization.type(), desensitization.startInclude(),
                            desensitization.endExclude());
                }
            }

            return serializerProvider.findValueSerializer(beanProperty.getType(), beanProperty);
        }
        return serializerProvider.findNullValueSerializer(null);
    }

}